import axios from "axios"
import type { AxiosRequestConfig } from "axios"
import dayjs from 'dayjs'
import { isObject } from "@/service/type-utils"

export function downloadFile(data: any, name: string) {
  if(!/\./.test(name)) {
    return console.warn('下载文件应有正常的后缀名')
  }

  let nameList = name.split('.')
  let contentType, type = nameList[nameList.length - 1]

  switch(type) {
    case 'xlsx':
      contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      break
    case 'xls':
      contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      break
    case 'zip':
      contentType = 'application/zip'
      break
    case 'csv':
      contentType = 'text/csv'
      break
    case 'txt':
      contentType = 'text/plain'
      break
    case 'png':
      contentType = 'application/x-png'
      break
    case 'jpg':
      contentType = 'application/x-jpg'
      break
    case 'pdf':
      contentType = 'application/pdf'
      break
    case 'gif':
      contentType = 'image/gif'
      break
    case 'jpeg':
      contentType = 'image/jpeg'
      break
    case 'doc':
      contentType = 'application/msword'
      break
    case 'docx':
      contentType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
      break
    case 'ppt':
      contentType = 'application/x-ppt'
      break
  }

  const blob = new Blob([data], { type: contentType })
  const url = window.URL.createObjectURL(blob)

  // 以动态创建a标签进行下载
  const a = document.createElement('a')
  const fileName = dayjs(new Date()).format('YYYYMMDD') + '_' +  name
  a.href = url
  a.download = fileName
  a.click()
  window.URL.revokeObjectURL(url)
}
const mapCancel = new Map()
const CancelToken = axios.CancelToken

export const getPendingUrl = (config: AxiosRequestConfig) => [
  config.method,
  config.url,
  isObject( config.data ) ? JSON.stringify( config.data  ) : config.data
].join('&')

export class axiosCancel {

  addCancel(config: AxiosRequestConfig) {
    // 清除当前正在请求的相同的url
    this.removeCancel(config)

    const url = getPendingUrl(config)
    config.cancelToken = config?.cancelToken || new CancelToken((cancel) => {
      if(!mapCancel.has(url)) {
        mapCancel.set(url, cancel)
      }
    })
  }

  removeCancel(config) {
    const url = getPendingUrl(config)
    if(mapCancel.has(url)) {
      const cancel = mapCancel.get(url)
      cancel && cancel()
      mapCancel.delete(url)
    }
  }

  removeAllCancel() {
    mapCancel.forEach(cancel => {
      cancel && cancel()
    })
    mapCancel.clear()
  }

}
